package XianCheng.线程安全问题;

public class TestSynchronized {
      /*
            synchronized(同步监视器){
                  //需要被同步的代码：就是说在被这个包裹以后，就使得一个线程在操作这些代码的过程中，其他线程必须等待.
            }

            同步监视器(锁)：决定哪个线程来执行下面这段代码，换句话说，哪个线程获得了同步监视器，哪个线程就调用被同步代码块所执行的代码。
            同步监视器：可以使用任何一个类的对象来充当，但是，多个线程必须共用一个。
       */

      //如何看synchronized()当中，括号如何判断唯一当我只写了一个Object obj=new Object()时？
      //答：就看从头到位又没有new第二个对象，如果有就不是唯一的，也就是不可以的。

      //一个类创建一个对象，被多个线程所共用


      /*
            Test test=new Test();
            Thread t1=new Thread(test);
            Thread t2=new Thread(test);
            Thread t3=new Thread(test);
       */
      public static void main(String[] args) {
            Account acct = new Account();
            //这样一个acct对象供两个Customer共用
            Customer custom1 = new Customer(acct, "lgzs");
            Customer custom2 = new Customer(acct, "gaoal");

            custom1.start();
            custom2.start();
      }
}

class Account {

      private double balance;//余额(共享数据)

      //因为synchronized出现Account的类当中，所以看下Account创建的对象是否唯一，如果唯一，那么synchronized就可以使用了。
      public synchronized void deposit(double amt) {
            if (amt > 0) {
                  balance += amt;
            }
            try {//为什么加了这个就会出现线程安全性异常
                  Thread.sleep(1000);
            } catch (Exception e) {
                  e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "存钱1000块,余额为" + balance);
      }
}

class Customer extends Thread {//如何能new一个Account而两个Customer公用呢?

      Account account;

      String name;

      public Customer(Account account) {
            this.account = account;
      }

      public Customer(Account account, String name) {
            super(name);
            this.account = account;
      }

      @Override
      public void run() {
            for (int i = 0; i < 3; i++) {
                  //操作这个账户的余额，让这个账户的余额发生三次增加
                  account.deposit(1000);//在Thread重写的run()方法中调用account的deposit()方法。
            }
      }

}
